package org.jetlinks.pro.cassandra.metadata;

import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections.CollectionUtils;
import org.hswebframework.ezorm.core.meta.Feature;
import org.hswebframework.ezorm.rdb.executor.DefaultBatchSqlRequest;
import org.hswebframework.ezorm.rdb.executor.PrepareSqlRequest;
import org.hswebframework.ezorm.rdb.executor.SqlRequest;
import org.hswebframework.ezorm.rdb.metadata.RDBColumnMetadata;
import org.hswebframework.ezorm.rdb.metadata.RDBIndexMetadata;
import org.hswebframework.ezorm.rdb.metadata.RDBTableMetadata;
import org.hswebframework.ezorm.rdb.metadata.dialect.DataTypeBuilder;
import org.hswebframework.ezorm.rdb.operator.DDLOperator;
import org.hswebframework.ezorm.rdb.operator.DatabaseOperator;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.PrepareSqlFragments;
import org.hswebframework.ezorm.rdb.operator.builder.fragments.ddl.CreateTableSqlBuilder;

import java.util.stream.Collectors;

/**
 * Cassandra创建表SQL构造器，用于cassandra进行ddl create table 时生成SQL.
 *
 * 支持设置主键{@link CassandraPrimaryKeyBuilder},默认排序{@link ClusteringOrderBy},以及索引
 *
 * @author zhouhao
 * @see CreateTableSqlBuilder
 * @see DatabaseOperator#ddl()
 * @see DDLOperator#createOrAlter(String)
 * @see CassandraPrimaryKeyBuilder
 * @see ClusteringOrderBy
 * @see RDBTableMetadata#addFeature(Feature)
 * @since 1.11
 */
@SuppressWarnings("all")
@Getter
@Setter
public class CassandraCreateTableSqlBuilder implements CreateTableSqlBuilder {

    @Override
    public SqlRequest build(RDBTableMetadata table) {
        //使用create table if not exists,防止重复创建时报错.
        PrepareSqlFragments sql = PrepareSqlFragments.of("create table if not exists");

        sql.addSql(table.getFullName(), "(");

        int index = 0;
        //列名
        for (RDBColumnMetadata column : table.getColumns()) {
            if (index++ > 0) {
                sql.addSql(",");
            }
            DataTypeBuilder typeBuilder = ((DataTypeBuilder) column.getType());

            sql.addSql(column.getQuoteName(), typeBuilder.createColumnDataType(column));

        }
        //主键
        table.findFeatureNow(CassandraPrimaryKeyBuilder.ID)
             .builderPrimaryKey(table)
             .map(CassandraPrimaryKey::toSql)
             .ifPresent(key -> {
                 sql.addSql(",primary key (", key, ")");
             });

        sql.addSql(")");

        //默认排序
        table.getFeature(ClusteringOrderBy.ID)
             .map(ClusteringOrderBy::toSQL)
             .ifPresent(sql::addSql);

        //有设置索引
        if (CollectionUtils.isNotEmpty(table.getIndexes())) {
            DefaultBatchSqlRequest batch = new DefaultBatchSqlRequest();
            //先创建表
            batch.addBatch(sql.toRequest());

            //再创建索引
            for (RDBIndexMetadata tableIndex : table.getIndexes()) {
                batch.addBatch(
                    PrepareSqlFragments
                        .of()
                        //使用create index if not exists,防止重复创建时报错.
                        .addSql("create index if not exists", tableIndex.getName(), "on", table.getFullName())
                        .addSql(tableIndex
                                    .getColumns()
                                    .stream()
                                    .map(column -> table.getDialect().quote(column.getColumn()))
                                    .collect(Collectors.joining(",", "(", ")"))
                        )
                        .toRequest()
                );
            }
            return batch;
        }
        return sql.toRequest();
    }

}
